<template>
<div style="width:100%;height:100%;">
  <div id="label"></div>
  <div id="container" ></div>
</div>
</template>

<script>
var THREE = require('three');
var OrbitControls = require('three-orbitcontrols');
var DragControls = require('three-dragcontrols');
import { RenderPass, EffectComposer, OutlinePass } from "three-outlinepass"
// import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OBJLoader, MTLLoader } from "three-obj-mtl-loader";
export default {
 data () {
    return {
      camera:null,
      scene:null,
      renderer:null,
      mesh:null,
      controls:null,
      container:null,
      planeMat:null,
      RackMat:null,
      RackMat2:null,
      CargoMat:null,
      LineMat:null,
      RollMat:null,
      stats:null,
      outlinePass:null,
      compose:null,
      wallMatA:[],
      wallMatB:[],
      selectedObjects:[],
    }
  },
  methods:{
    init(){
      this.initMat();
      this.initScene();
      this.initCamera();
      this.initLight();
      this.initStats();
      this.initRenderer();
      this.initControls();
      this.createFloor();
      this.animate();
      // this.dragFun();
      setInterval(()=>{
        this.scene.getObjectByName('货物4').position.x += 3;
      },100)
    },
    /**初始化场景 */
     initScene() {
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.CubeTextureLoader()
                .setPath('../../static/skybox/').load(
                    [
                    '远山_RT.jpg', // right
                    '远山_LF.jpg', // left
                    '远山_UP.jpg', // top
                    '远山_DN.jpg', // bottom
                    '远山_BK.jpg', // back
                    '远山_FR.jpg'  // front
                    ]
                );
      this.fontStyle(font=>{
        this.addArea(-800,360,300,550,this.scene,"发动机区","FF0000",24,font); //库区线和名字
        this.addArea(-800,-360,300,550,this.scene,"轴承区","FF0000",24,font); 
        this.addArea(-400,360,300,550,this.scene,"油缸区","FF0000",24,font); 
        this.addArea(-400,-360,300,550,this.scene,"配件区","FF0000",24,font); 
        this.addArea(0,360,300,550,this.scene,"xx区","FF0000",24,font); 
        this.addArea(0,-360,300,550,this.scene,"xx区","FF0000",24,font); 
        this.addArea(400,360,300,550,this.scene,"xx区","FF0000",24,font); 
        this.addArea(400,-360,300,550,this.scene,"xx区","FF0000",24,font); 
        this.addArea(800,360,300,550,this.scene,"xx区","FF0000",24,font); 
        this.addArea(800,-360,300,550,this.scene,"xx区","FF0000",24,font); 
      })
      //增加货物
      this.addCargo(-900,200,0,50,50,50,this.scene,'货物1')
      this.addCargo(-900,300,0,50,50,50,this.scene,'货物2')
      this.addCargo(-900,400,0,50,50,50,this.scene,'货物3')
      this.addColorCargo(-800,200,0,50,50,50,this.scene,'货物4')
      this.addGltfCargo()
      //创建墙
      this.createCubeWall(10, 1400, 200, 0, this.wallMatA, -1295, 0, 100, "墙面"); //上
      this.createCubeWall(10, 1400, 200, 0, this.wallMatA, 1295, 0, 100, "墙面"); //下
      this.createCubeWall(200, 10, 2600, 0.5, this.wallMatB, 0, -700, 100, "墙面"); //左
      this.createCubeWall(200, 10, 2600, 0.5, this.wallMatB, 0, 700, 100, "墙面"); //右
      //创建门
      this.createDoor_left(100, 12, 180, 1, -1100, 700, 90, "左门1");
      this.createDoor_right(100, 12, 180, 1, -1200, 700, 90, "右门1");
      this.createDoor_left(100, 12, 180, 0.5, 1295, -400, 90, "左门2");
      this.createDoor_right(100, 12, 180, 0.5, 1295, -300, 90, "右门2");
      //事件监听
      window.addEventListener( 'click', this.onMouseClick, false);
      window.addEventListener('resize', this.onWindowResize, false);
      //点击效果


      
    },
    /**点击效果 */
    selectLight(){
      //渲染点击效果
      this.compose = new EffectComposer(this.renderer);
      var renderPass = new RenderPass( this.scene, this.camera);
      this.outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth,window.innerHeight), this.scene,this.camera);
      this.outlinePass.renderToScreen = true;
      this.outlinePass.selectedObjects = this.selectedObjects;

      this.compose.addPass(renderPass);
      this.compose.addPass(this.outlinePass);

      var params = {
          edgeStrength: 1,//包围线浓度
          edgeGlow: 0.5,//边缘线范围
          edgeThickness: 1,//边缘线浓度
          pulsePeriod: 0,//包围线闪烁评率
          usePatternTexture: false
      };
      this.outlinePass.edgeStrength = params.edgeStrength;
      this.outlinePass.edgeGlow = params.edgeGlow;
      this.outlinePass.visibleEdgeColor.set(0xffffff);//包围线颜色
      this.outlinePass.hiddenEdgeColor.set(0xff00ff);//被遮挡的边界线颜色
    },
    /**点击事件 */
    onMouseClick( event ) {
        var x, y;
        if ( event.changedTouches ) {
            x = event.changedTouches[ 0 ].pageX;
            y = event.changedTouches[ 0 ].pageY;
        } else {
            x = event.clientX;
            y = event.clientY;
        }
        var mouse = new THREE.Vector2();
        mouse.x = ( x / window.innerWidth ) * 2 - 1;
        mouse.y = - ( y / window.innerHeight ) * 2 + 1;
        var raycaster = new THREE.Raycaster();
        raycaster.setFromCamera( mouse, this.camera );
        var intersects = raycaster.intersectObjects( [ this.scene ], true );
        console.log('click',intersects)
         if (intersects.length > 0) {
        //选中第一个射线相交的物体
        var intersected = intersects[0].object;
        console.log(intersected.name)
           intersected.material.color.set( 0xff0000 );
    }

        
    },
    /**初始化相机 */
     initCamera() {
      this.camera = new THREE.PerspectiveCamera(70, this.container.clientWidth / this.container.clientHeight, 0.1, 10000);
      // this.camera.up.x = 0;
      // this.camera.up.y = 0;
      // this.camera.up.z = 1;
      this.camera.position.set(2000,0,2000);
      this.camera.lookAt(this.scene.position);
    },
    /**初始化灯光 */
     initLight() {
     

      // var directionalLight = new THREE.DirectionalLight(0xffffff, 0.3); //模拟远处类似太阳的光源
      // directionalLight.color.setHSL(0.1, 1, 0.95);
      // directionalLight.position.set(0, 200, 0).normalize();
      // this.scene.add(directionalLight);
      
      let spotLight = new THREE.DirectionalLight(0xffffff, 0.5);  //点光源
      spotLight.position.set(100, 200, 500);  
      spotLight.intensity = 0.6;
      this.scene.add(spotLight);

      // var spotLight = new THREE.SpotLight(0xffffff);
      // spotLight.position.set(500, 0, 500);
      // spotLight.castShadow = true;
      // this.scene.add(spotLight);

      var ambient = new THREE.AmbientLight(0xffffff, 0.8); //环境光能保持整体都是亮点
      ambient.position.set(0, 40, 0);
      this.scene.add(ambient);
      
    },
    /**初始化渲染器 */
     initRenderer() {
      this.renderer = new THREE.WebGLRenderer({
        antialias: true, // 抗锯齿
      });
      this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
      this.renderer.setClearColor(0x4682B4, 1.0);//天空色
      this.container.appendChild(this.renderer.domElement);
      // this.selectLight();
    },
    /**resize */
    onWindowResize() {
          this.camera.aspect = window.innerWidth / window.innerHeight;
          this.camera.updateProjectionMatrix();
          this.renderer.setSize(window.innerWidth, window.innerHeight);
    },
    /**初始化轨迹球控件 */
     initControls() {
      //辅助网格 蓝-z 红-x 绿-y
      let axisHelper = new THREE.AxesHelper(2000)
      this.scene.add(axisHelper)
      this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;
      this.controls.enableZoom = true;
      this.controls.dampingFactor = 0.5;
      // 视角最小距离
      this.controls.minDistance = 5;
      // 视角最远距离
      this.controls.maxDistance = 4000;
      // 最大角度
      this.controls.maxPolarAngle = Math.PI/2;
      this.controls.target = new THREE.Vector3(50,50,50);
    },
    /**创建地板 */
     createFloor() {
      var loader = new THREE.TextureLoader();
      loader.load("../../static/ThreeJs/images/floor.jpg", (texture)=>{
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(10, 10);
        var floorGeometry = new THREE.PlaneGeometry(2600,1400,1); //模型
        var floorMaterial = new THREE.MeshBasicMaterial({  //材质
          map: texture,
        });
        var floor = new THREE.Mesh(floorGeometry, floorMaterial);// 网络模型对象
        floor.name = "地面";
        this.scene.add(floor);
      });
    },
    /**初始化性能插件 */
     initStats() {
      this.stats = new Stats();
      this.stats.setMode(0);
      this.stats.domElement.style.position = 'absolute';
      this.stats.domElement.style.left = '0px';
      this.stats.domElement.style.top = '0px';
      this.container.appendChild(this.stats.domElement);
    },
    //拖动事件
    dragFun(){
      var objects=[];
      var dragControls = new THREE.DragControls( objects, this.camera, this.renderer.domElement );
      var controls = new THREE.OrbitControls(this.camera);//创建控件对象
      dragControls.addEventListener( 'dragstart', function ( event ) {
          controls.enabled = false;
          isPaused = true;
      } );
      dragControls.addEventListener( 'dragend', function ( event ) {
          controls.enabled = true;
          isPaused = false;
      } );
    },
    /**字体 */
    fontStyle(cb){
      new THREE.FontLoader().load('../../static/ThreeJs/FZYaoTi_Regular.json',(font)=>{
          cb(font);
      })
    },
    //region 库区
    /** 放置虚线框区域和库区名称 */
    addArea(x,y,width,length,scene,name,textColor,font_size,font) {
         this.addPlane(x,y,width,length,scene);
         
            ////加入立体文字
            var text= new THREE.TextGeometry(name,{
                // 设定文字字体
                font:font,
                //尺寸
                size:font_size,
                //厚度
                height:1
            });
            //3D文字材质
            var m = new THREE.MeshStandardMaterial({color:"#" + textColor});
            var mesh = new THREE.Mesh(text,m)
            mesh.position.x = x - width/2 - 30;
            mesh.position.y = y - length/2 + 8;
            mesh.position.z = 1.3;
            mesh.rotation.z = Math.PI / 2.0;
            scene.add(mesh);
        // });
    },
    /** 放置单个货物 */
    addCargo(x,y,z,box_x,box_y,box_z,scene,name) {
        var geometry = new THREE.BoxGeometry( box_x, box_y, box_z );
        var obj = new THREE.Mesh( geometry, this.CargoMat );
        obj.position.set(x,y,z+box_z/2);
        obj.name = name;
        scene.add(obj);
        return obj;
    },
    /** 放置彩色货物 */
    addColorCargo(x,y,z,box_x,box_y,box_z,scene,name) {
        var geometry = new THREE.BoxGeometry( box_x, box_y, box_z );
        var CargoMat= new THREE.MeshLambertMaterial({color: 0x44ff44});
        var obj = new THREE.Mesh( geometry, CargoMat );
        obj.position.set(x,y,z+box_z/2);
        obj.name = name;
        scene.add(obj);
        return obj;
    },
    /** 放置GLTF模型货物 */
    addGltfCargo() {
      //  var loader = new GLTFLoader();
      //  for(var i=0;i<5;i++){
      //   //  loader.load( 'https://a.amap.com/jsapi_demos/static/gltf/Duck.gltf',  ( gltf )=> { 
      //    loader.load( '../../static/models/jichuanggltf.gltf',  ( gltf )=> { 
      //         console.log(gltf);
      //         gltf.scene.rotation.x = Math.PI/2;
      //         gltf.scene.scale.set(100,100,100)
      //         gltf.scene.position.x = Math.random()*i*20;
      //         gltf.scene.position.y = Math.random()*i*20;
      //         gltf.scene.position.z = Math.random()*i*20;
      //         gltf.Name="duck";
      //         console.log('s',gltf.scene.name)
      //         this.scene.add(gltf.scene);
      //   })
      //  }


      var OBJLoader = new THREE.OBJLoader(); //obj加载器
      var MTLLoader = new THREE.MTLLoader(); //材质文件加载器
      MTLLoader.load('../../static/贴图/002.mtl', (materials) =>{ //材质没有
        // 返回一个包含材质的对象MaterialCreator
        console.log(materials);
        //obj的模型会和MaterialCreator包含的材质对应起来
        OBJLoader.setMaterials(materials);
        OBJLoader.load('../../static/贴图/002.obj', (obj)=> {
          console.log(obj);
          var mesh = obj.children[0];
              mesh.rotateX(-Math.PI/2);
              mesh.translateY(-1500);
              mesh.name="dxl"
          // mesh.material = new THREE.MeshBasicMaterial({
          //     map: new THREE.TextureLoader().load('../../static/贴图/002.png'),
          //     side: THREE.DoubleSide,
          //     transparent: true,
          //     clipIntersection: true,
          // });
          mesh.material =new THREE.MeshLambertMaterial({color: 0x44ff44})
          this.scene.add(obj); //返回的组对象插入场景中
          // 加载后操作
          obj.children[0].scale.set(50, 50, 50); //缩放球体网格模型
         
        })
      })
       
    },
    /** 初始化材质信息 */
    initMat() {
        this.planeMat = new THREE.MeshLambertMaterial();
        this.RackMat = new THREE.MeshLambertMaterial();
        this.RackMat2 = new THREE.MeshPhongMaterial({color:0x1C86EE});
        this.CargoMat = new THREE.MeshLambertMaterial();
        this.LineMat = new THREE.MeshLambertMaterial();
        this.RollMat = new THREE.MeshLambertMaterial();

        new THREE.TextureLoader().load( '../../static/ThreeJs/images/plane.png', ( map )=>{
            this.planeMat.map = map;
            this.planeMat.transparent = true;
            this.planeMat.opacity = 0.8;
            this.planeMat.needsUpdate = true;
        } );
        new THREE.TextureLoader().load( "../../static/ThreeJs/images/rack.png", ( map )=> {
            this.RackMat.map = map;
            this.RackMat.needsUpdate = true;
        } );
        new THREE.TextureLoader().load( "../../static/ThreeJs/images/box.png", ( map )=> {
            this.CargoMat.map = map;
            this.CargoMat.needsUpdate = true;
        } );
        new THREE.TextureLoader().load( "../../static/ThreeJs/images/line.png", ( map )=> {
            this.LineMat.map = map;
            this.LineMat.needsUpdate = true;
        } );
       var RollTexture = new THREE.TextureLoader().load( "../../static/ThreeJs/images/biaoyu.png", ( map )=> {
            this.RollMat.map = map;
            this.RollMat.needsUpdate = true;
            this.RollMat.transparent = true;
            this.RollMat.side = THREE.DoubleSide;
        } );
        RollTexture.wrapS = THREE.RepeatWrapping;
        RollTexture.wrapT=THREE.RepeatWrapping;

        //初始化墙材料
        this.createwallMatAerail();
    },
    /**region 矩形区域 */
    addPlane(x,y,width,length,scene) {

        // var geometry = new THREE.BoxGeometry(5, 5, 5); //创建一个立方体几何对象Geometry
        // // 点渲染模式
        // var material = new THREE.PointsMaterial({
        //   color: 0xff0000,
        //   size: 5.0 //点对象像素尺寸
        // }); //材质对象
        // var points = new THREE.Points(geometry, material); //点模型对象
        // points.position.set(x,y,1); //库区中心点
        // scene.add( points );
        var LineMat=new THREE.MeshBasicMaterial({
                      color: 0xffffff,
                      side: THREE.DoubleSide,
                    })
        var lineWidth = 8
        var geometry = new THREE.PlaneGeometry( lineWidth, length );
        var obj = new THREE.Mesh( geometry, LineMat );
        obj.position.set(x,y,2);
        var obj2 = obj.clone();
        obj2.translateX(width);

        var geometry2 = new THREE.PlaneGeometry( width,lineWidth);
        var obj3 = new THREE.Mesh( geometry2, LineMat );
        obj3.position.set(x+width/2,y-length/2+lineWidth/2,2);
        var obj4 = obj3.clone();
        obj4.translateY(length-lineWidth);

        var group = new THREE.Group();
        group.add(obj);
        group.add(obj2);
        group.add(obj3);
        group.add(obj4);
        group.translateX(-width/2);
        this.scene.add( group );
    },
    //创建墙纹理
    createwallMatAerail(){
        this.wallMatA = []; //上下墙
        this.wallMatA.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //前 
        this.wallMatA.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //后  0x9cb2d1：淡紫
        this.wallMatA.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //上  0xd6e4ec： 偏白色
        this.wallMatA.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //下
        this.wallMatA.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //左   
        this.wallMatA.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //右
        this.wallMatB = []; //左右墙
        this.wallMatB.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //前 
        this.wallMatB.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //后  0x9cb2d1：淡紫
        this.wallMatB.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //上  0xd6e4ec： 偏白色
        this.wallMatB.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //下
        this.wallMatB.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //左   
        this.wallMatB.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //右
     },
    /**创建墙 */
    createCubeWall(width, height, depth, angle, material, x, y, z, name) {
      var cubeGeometry = new THREE.BoxGeometry(width, height, depth);
      var cube = new THREE.Mesh(cubeGeometry, material);
      cube.position.x = x;
      cube.position.y = y;
      cube.position.z = z;
      cube.rotation.y = angle * Math.PI; //-逆时针旋转,+顺时针
      cube.name = name;
      this.scene.add(cube);
    },
     /**创建门_左侧 */
     createDoor_left(width, height, depth, angle, x, y, z, name) {
      var loader = new THREE.TextureLoader();
      loader.load("../../static/ThreeJs/images/door_left.png", (texture)=> {
        var doorgeometry = new THREE.BoxGeometry(width, height, depth);
        var doormaterial = new THREE.MeshBasicMaterial({
          map: texture,
          color: 0xffffff
        });
        doormaterial.opacity = 1.0;
        doormaterial.transparent = true;
        var door = new THREE.Mesh(doorgeometry, doormaterial);
        door.position.set(x, y, z);
        door.rotation.z = angle * Math.PI; //-逆时针旋转,+顺时针
        door.name = name;
        this.scene.add(door);
      });
    },
    /**创建门_右侧 */
     createDoor_right(width, height, depth, angle, x, y, z, name) {
      var loader = new THREE.TextureLoader();
      loader.load("../../static/ThreeJs/images/door_right.png", (texture)=>{
        var doorgeometry = new THREE.BoxGeometry(width, height, depth);
        var doormaterial = new THREE.MeshBasicMaterial({
          map: texture,
          color: 0xffffff
        });
        doormaterial.opacity = 1.0;
        doormaterial.transparent = true;
        var door = new THREE.Mesh(doorgeometry, doormaterial);
        door.position.set(x, y, z);
        door.rotation.z = angle * Math.PI; //-逆时针旋转,+顺时针8
        door.name = name;
        this.scene.add(door);
      });
    },
    /**渲染动画 */
    animate(){
      var clock = new THREE.Clock();
      var delta = clock.getDelta();
      // this.scene.getObjectByName('货物4').position.x += 1;
      requestAnimationFrame(this.animate);
      this.renderer.render( this.scene, this.camera);
      this.controls.update(delta);
      this.stats.update(delta);
      // this.compose.render(delta);
    },
  },
  mounted(){
    this.container=document.getElementById('container');
    this.init();
  },
  beforeDestory(){
      this.scene.dispose();
      this.compose.dispose();
      this.controls.dispose();
  }
}
</script>

<style scoped>
#container{
  width:100%;
  height:100%;
}
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
